<!--
 * @Author: Dorange.Wang
 * @Date: 2021-03-31 15:19:31
 * @LastEditors: wangming
 * @LastEditTime: 2021-12-06 16:29:49
 * @Description: file content
-->
<route>
{
  "meta":{
    "title":"业务模型详情"
  }
}
</route>
<template>
  <div>
    <div class="operation-right">
      <el-row :gutter="12" align="middle" type="flex">
        <el-col class="label-ellipsis">模型名称：{{ modelInfo.name }}</el-col>
        <el-col class="label-ellipsis">
          模型编码：{{ modelInfo.code }}
          <el-button
            type="text"
            @click="copy(modelInfo.code)"
            icon="el-icon-document-copy"
          ></el-button>
        </el-col>
        <el-col class="label-ellipsis"
          >模型类型：{{
            modelInfo.type === "ENTITY" ? "实体模型" : "虚拟模型"
          }}</el-col
        >
        <el-col class="tr">
          <el-select
            style="width: 120px"
            v-model="curVer"
            placeholder="请选择版本"
            @change="loadData(1)"
          >
            <el-option
              v-for="ver in verList"
              :key="ver.id"
              :value="ver.id"
              :label="ver.version | version"
            >
            </el-option>
          </el-select>
          <el-dropdown
            class="ml10"
            @command="handlePublish"
            placement="bottom-end"
            trigger="click"
            size="medium"
          >
            <el-button type="primary">
              发布<i class="el-icon-arrow-down el-icon--right"></i>
            </el-button>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item v-if="verList.length === 0" command="by-script"
                >基于草稿发布</el-dropdown-item
              >
              <el-dropdown-item
                v-if="verList.length !== 0"
                :disabled="!curVer"
                command="by-publish"
                >基于版本发布</el-dropdown-item
              >
              <el-dropdown-item
                v-if="verList.length !== 0"
                command="by-multi-version"
                >跨版本发布</el-dropdown-item
              >
            </el-dropdown-menu>
          </el-dropdown>
        </el-col>
      </el-row>
      <el-row class="mt10 mb15" align="middle" type="flex">
        <el-col class="label-ellipsis"
          >模型描述：{{ modelInfo.description }}</el-col
        >
      </el-row>
    </div>
    <div class="operation-row">
      <el-tabs v-model="activeTab" @tab-click="handleTabClick">
        <el-tab-pane
          v-for="(value, key) in MODULE_TAB_ENUM"
          :key="key"
          :label="value"
          :name="key"
        >
        </el-tab-pane>
      </el-tabs>
    </div>
    <!--    字段-->
    <div v-show="activeTab === 'FIELD'">
      <el-row :gutter="12">
        <el-col :span="6">
          <el-input
            v-model="queryData.searchKey"
            placeholder="请输入编码或名称"
            size="small"
            clearable
            :maxlength="64"
            prefix-icon="el-icon-search"
          >
            <el-button
              slot="append"
              icon="el-icon-search"
              @click="loadData(1)"
            ></el-button>
          </el-input>
        </el-col>
        <el-col :span="6">
          <el-button
            style="margin-left: 20px"
            type="primary"
            size="small"
            @click="handleCreate"
            >新建</el-button
          >
        </el-col>
        <!-- 实体业务模型隐藏系统字段-->
        <el-checkbox
          v-if="modelInfo.type === 'ENTITY'"
          style="float: right; margin-right: 10px"
          v-model="hiddenSystemField"
          @change="changeHiddenSystemField"
          >隐藏系统字段</el-checkbox
        >
      </el-row>

      <el-table
        ref="table"
        class="mt10"
        :data="tableData"
        v-loading="loading"
        style="width: 100%"
        current-row-key="id"
        stripe
        border
        highlight-current-row
      >
        <el-table-column prop="code" label="编码">
          <template slot-scope="scope">
            {{ scope.row.code }}
            <i
              v-if="modelInfo.type === 'ENTITY' && scope.row.code === 'id'"
              class="el-icon-key"
            ></i>
          </template>
        </el-table-column>
        <!-- <el-table-column prop="code" label="编码"/> -->
        <el-table-column prop="name" label="名称" />
        <el-table-column prop="type" label="数据类型">
          <template slot-scope="scope">
            {{
              scope.row.builtIn && scope.row.code !== "process_title"
                ? "--"
                : scope.row.type | fieldDataType
            }}
          </template>
        </el-table-column>
        <el-table-column prop="length" label="长度">
          <template slot-scope="scope">
            {{ scope.row.type === "SHORT_TEXT" ? scope.row.length : "" }}
          </template>
        </el-table-column>
        <el-table-column prop="nullable" label="允许为空">
          <template slot-scope="scope">
            <el-checkbox
              disabled
              :true-label="1"
              :false-value="0"
              v-model="scope.row.nullable"
            ></el-checkbox>
          </template>
        </el-table-column>
        <el-table-column prop="createType" label="类型">
          <template slot-scope="scope">
            {{ scope.row.createType | fieldCreateType }}
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态">
          <template slot-scope="scope">
            <span :class="{ 'script-color': scope.row.status === 'SCRIPT' }">{{
              scope.row.status | fieldStatus
            }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="actions" label="操作">
          <template slot-scope="scope">
            <span
              class="table-actionItem"
              v-if="
                ['BUILTIN', 'USER_DEFINED'].includes(scope.row.createType) ||
                !scope.row.builtIn ||
                modelInfo.type === 'VIRTUAL' ||
                (scope.row.builtIn && scope.row.code === 'process_title')
              "
            >
              <el-button type="text" @click="handleEdit(scope.row)"
                >编辑</el-button
              >
            </span>
            <span
              class="table-actionItem"
              v-if="curVer && scope.row.serialNum > minSerialNum"
            >
              <el-button type="text" @click="handleMove(scope.row, 'up')"
                >上移</el-button
              >
            </span>
            <span
              class="table-actionItem"
              v-if="
                curVer &&
                scope.row.status !== 'SCRIPT' &&
                scope.row.serialNum < maxSerialNum
              "
            >
              <el-button type="text" @click="handleMove(scope.row, 'down')"
                >下移</el-button
              >
            </span>
            <span
              class="table-actionItem"
              v-if="
                scope.row.createType === 'USER_DEFINED' ||
                (!scope.row.builtIn &&
                  ![
                    'parent_id',
                    'parent_ids',
                    'children',
                    'node_name',
                    'serial_num',
                  ].includes(scope.row.code)) ||
                modelInfo.type === 'VIRTUAL'
              "
            >
              <el-popconfirm
                :title="
                  scope.row.status === 'SCRIPT'
                    ? '确定要删除该字段吗？'
                    : '该字段已发布，删除后数据无法恢复，确认要删除吗？'
                "
                placement="top"
                @confirm="handleDelete(scope.row)"
              >
                <el-button class="link-danger" type="text" slot="reference"
                  >删除</el-button
                >
              </el-popconfirm>
            </span>
          </template>
        </el-table-column>
      </el-table>
      <div class="tr mt24">
        <x-pagination
          :total="total"
          :pageSize.sync="pageData.pageSize"
          :pageNo.sync="pageData.pageNo"
          @search="loadData"
        />
      </div>
    </div>
    <!--业务服务-->
    <ServiceList
      v-show="activeTab === 'BUSINESS'"
      ref="ServiceList"
      :modelInfo="modelInfo"
    />
    <!--    数据服务-->
    <DataList
      v-show="activeTab === 'DATA'"
      ref="DataList"
      :modelInfo="modelInfo"
    />
    <!--     验证规则-->
    <RuleList
      v-show="activeTab === 'RULE'"
      ref="RuleList"
      :modelInfo="modelInfo"
    />
    <!-- 索引 -->
    <TableIndex
      v-show="activeTab === 'TABLE_INDEX'"
      ref="TableIndex"
      :modelInfo="modelInfo"
    />
    <!--    关联状态机-->
    <div v-show="activeTab === 'STATE'">
      <el-row class="mt20 mb20">
        状态机key：
        <el-button type="text" size="medium" @click="handleOpenState">{{
          stateInfo.key
        }}</el-button>
      </el-row>
      <el-row> 状态机名称： {{ stateInfo.name }} </el-row>
    </div>
    <!-- 触发器 -->
    <TriggerList
      ref="TriggerList"
      v-show="activeTab === 'TRIGGER'"
      :modelInfo="modelInfo"
    />
    <!-- 数据导入导出模版 -->
    <DataImportExportList
      ref="DataImportExportList"
      v-show="activeTab === 'DATAIMPORTEXPORT'"
      :modelInfo="modelInfo"
    />
    <!--    关联流程-->
    <div v-show="activeTab === 'PROCESS'">
      <el-table
        class="mt10"
        :data="processData"
        v-loading="loading"
        style="width: 100%"
        current-row-key="id"
        stripe
        border
        highlight-current-row
      >
        <el-table-column prop="key" label="流程key">
          <template slot-scope="scope">
            <el-button type="text" @click="handleOpenProcess(scope.row)">{{
              scope.row.key
            }}</el-button>
          </template>
        </el-table-column>
        <el-table-column prop="name" label="流程名称"> </el-table-column>
      </el-table>
    </div>
    <PublishForm ref="PublishForm" />
    <RuleErrorModal ref="RuleErrorModal"></RuleErrorModal>
  </div>
</template>

<script>
import { MODULE_TAB_ENUM } from "@/utils/enum";

import { getHmmodelInfo } from "@/apis/paas/HmModelController.js";
import { getHmprocessModelList } from "@/apis/paas/HmProcessController.js";
import { getHmstatemodelKeyInfo } from "@/apis/paas/HmStateModelController.js";
import {
  getHmentitymodelPageList,
  deleteHmentitymodel,
} from "@/apis/paas/HmEntityModelController.js";
import {
  getHmmodelpublishList,
  postHmmodelpublishByscript,
  postHmmodelpublishBypublish,
  postHmmodelpublishBymultiversion,
} from "@/apis/paas/HmModelPublishController.js";
import {
  getHmpublishedentitymodelPageList,
  putHmpublishedentitymodelMoveup,
  putHmpublishedentitymodelMovedown,
} from "@/apis/paas/HmPublishedEntityModelController.js";

import FieldForm from "./__components__/fieldForm";
import PublishForm from "./__components__/PublishForm";
import ServiceList from "./__components__/Services/ServiceList";
import RuleList from "./__components__/ValidatorRule/RuleList";
import DataList from "./__components__/DataService/DataList";
import { copy } from "@/utils/util";
import RuleErrorModal from "./__components__/RuleErrorModal";
import TriggerList from "./__components__/trigger/TriggerList";
import TableIndex from "./__components__/tableIndex/TableIndex";
import DataImportExportList from "./__components__/DataImportExport/List.vue";

export default {
  name: "ModelInfo",
  components: {
    PublishForm,
    ServiceList,
    RuleList,
    RuleErrorModal,
    DataList,
    TriggerList,
    TableIndex,
    DataImportExportList,
  },
  data() {
    return {
      copy,
      MODULE_TAB_ENUM,
      activeTab: Object.keys(MODULE_TAB_ENUM)[0],
      hiddenSystemField: true,
      loading: false,
      queryData: {},
      pageData: {
        pageSize: 10,
        pageNo: 1,
      },
      minSerialNum: 0,
      maxSerialNum: 0,
      tableData: [],
      stateInfo: {},
      processData: [],
      total: 0,
      curVer: "",
      verList: [],
      modelInfo: {},
    };
  },

  watch: {
    activeTab(value) {
      if (value === "BUSINESS") {
        this.$refs.ServiceList.init();
      } else if (value === "DATA") {
        this.$refs.DataList.init();
      } else if (value === "TABLE_INDEX") {
        this.$refs.TableIndex.init();
      }
    },
  },

  created() {
    this.init();
  },

  methods: {
    async init() {
      const { id } = this.$route.query;
      this._modelId = id;

      if (!id) {
        return;
      }

      const modelInfo = await this.loadModelInfo();

      this.getModuleTab();

      const { version } = modelInfo;

      if (version) {
        await this.loadVerList();
        const ver = this.verList.find(
          (item) => String(item.version) === String(version)
        );
        if (ver) {
          this.curVer = ver.id;
        }
      } else {
        this.loadVerList();
      }
      this.loadData();
    },

    async loadModelInfo() {
      return getHmmodelInfo({
        id: this._modelId,
      }).then((res) => {
        this.modelInfo = res;
        return res;
      });
    },

    loadData(pageNo = this.pageData.pageNo) {
      this.pageData.pageNo = pageNo;
      if (this.curVer) {
        this.loadVerFields(pageNo);
      } else {
        this.loadAllFields(pageNo);
      }
    },

    loadAllFields(pageNo = this.pageData.pageNo) {
      this.loading = true;
      getHmentitymodelPageList({
        ...this.queryData,
        ...this.pageData,
        pageNo,
        hiddenSystemField: this.hiddenSystemField,
        modelId: this._modelId,
      })
        .then((res) => {
          if (res.data.length === 0 && pageNo > 1) {
            this.loadVerFields(pageNo - 1);
            return;
          }
          if (this.modelInfo.type === "ENTITY") {
            this.tableData = res.data.map((item) => {
              return item;
            });
          } else {
            this.tableData = res.data;
          }
          this.total = res.totalCount;
        })
        .finally(() => {
          this.loading = false;
        });
    },

    loadVerFields(pageNo = this.pageData.pageNo) {
      this.loading = true;
      getHmpublishedentitymodelPageList({
        ...this.queryData,
        ...this.pageData,
        pageNo,
        hiddenSystemField: this.hiddenSystemField,
        publishId: this.curVer,
      })
        .then((res) => {
          if (res.data.length === 0 && pageNo > 1) {
            this.loadVerFields(pageNo - 1);
            return;
          }
          this.tableData = res.data.map((item) => {
            return item;
          });
          this.minSerialNum = res.extraInfo?.minSerialNum || 0;
          this.maxSerialNum = res.extraInfo?.maxSerialNum || 0;
          this.total = res.totalCount;
        })
        .finally(() => {
          this.loading = false;
        });
    },

    async loadVerList() {
      return getHmmodelpublishList({
        modelId: this._modelId,
      }).then((res) => {
        this.verList = res;
        return res;
      });
    },

    handleCreate() {
      FieldForm.addForm(
        {
          modelId: this._modelId,
          modelType: this.modelInfo.type,
        },
        this.modelInfo
      ).then(() => {
        // this.curVer = ''
        this.loadData();
        this.$message.success("新增成功");
      });
    },

    handleEdit(record) {
      FieldForm.editForm(
        {
          ...record,
          modelType: this.modelInfo.type,
        },
        this.modelInfo
      ).then(() => {
        this.loadData();
        this.$message.success("操作成功");
      });
    },

    handleMove(record, direction = "up") {
      let api = putHmpublishedentitymodelMoveup;
      if (direction === "down") {
        api = putHmpublishedentitymodelMovedown;
      }
      api({
        id: record.id,
        publishId: this.curVer,
      }).then(async () => {
        this.$message.success("操作成功");
        await this.loadData();
        this.setCurrentRow(record.id);
      });
    },

    setCurrentRow(id) {
      const row = this.tableData.find((item) => item.id === id);
      row && this.$refs.table.setCurrentRow(row);
    },

    handleDelete(record) {
      deleteHmentitymodel([record.id])
        .then((res) => {
          this.loadData();
          this.$message.success("操作成功");
        })
        .catch((e) => {
          if (e?.response?.status !== 700) return;
          const data = e?.response?.data || "";
          if (!data) return;
          this.$refs.RuleErrorModal.init(data);
        });
    },

    handlePublishByScript(data = {}) {
      postHmmodelpublishByscript(data).then((res) => {
        if (res) {
          this.curVer = res;
          this.loadVerList();
          this.loadData();
        }
        this.$message.success("操作成功");
        this.$refs.PublishForm.close();
      });
    },

    handlePublishByPublish(data = {}) {
      postHmmodelpublishBypublish(data).then((res) => {
        if (res) {
          this.curVer = res;
          this.loadVerList();
          this.loadData();
        }
        this.$message.success("操作成功");
        this.$refs.PublishForm.close();
      });
    },

    handlePublishByMultiVersion(data = {}) {
      postHmmodelpublishBymultiversion(data).then((res) => {
        if (res) {
          this.curVer = res;
          this.loadVerList();
          this.loadData();
        }
        this.$message.success("操作成功");
        this.$refs.PublishForm.close();
      });
    },

    handlePublish(command) {
      if (command === "by-script") {
        this.$refs.PublishForm.open(
          {
            command,
            modelInfo: this.modelInfo,
          },
          (data) => {
            this.handlePublishByScript({
              id: this._modelId,
              ...data,
            });
          }
        );
      } else if (command === "by-publish") {
        const verList = this.verList;
        const ver = this.verList.find((ver) => ver.id === this.curVer);
        const version = this.$options.filters["version"](ver.version);
        this.$refs.PublishForm.open(
          {
            command,
            verList,
            verId: this.curVer,
            version,
            modelInfo: this.modelInfo,
          },
          (data) => {
            this.handlePublishByPublish({
              // publishId: this.curVer,
              ...data,
            });
          }
        );
      } else if (command === "by-multi-version") {
        const verList = this.verList;
        this.$refs.PublishForm.open(
          {
            command,
            verList,
            modelInfo: this.modelInfo,
          },
          (data) => {
            this.handlePublishByMultiVersion({
              ...data,
              modelId: this._modelId,
            });
          }
        );
      }
    },
    changeHiddenSystemField(value) {
      this.loadData();
    },
    getModuleTab() {
      const obj = {
        FIELD: "数据字段",
        BUSINESS: "业务服务",
      };
      if (this.modelInfo.type === "VIRTUAL") {
        obj["DATA"] = "数据服务";
      }
      obj["RULE"] = "验证规则";
      obj["TRIGGER"] = "触发器";
      if (this.modelInfo.type === "ENTITY") {
        obj["TABLE_INDEX"] = "索引";
        obj["DATAIMPORTEXPORT"] = "数据导入导出模版";
      }
      if (this.modelInfo.supportProcess) {
        obj["PROCESS"] = "关联流程";
        this.getHmprocessModelList();
      }
      if (this.modelInfo.supportStateModel) {
        obj["STATE"] = "关联状态机";
        this.getHmstatemodelKeyInfo();
      }
      this.MODULE_TAB_ENUM = obj;
    },
    // 获取状态机详情
    getHmstatemodelKeyInfo() {
      getHmstatemodelKeyInfo({ key: this.modelInfo.stateModelKey }).then(
        (res) => {
          this.stateInfo = res;
        }
      );
    },
    // 查看状态机
    handleOpenState() {
      const { origin, pathname } = window.location;
      const { id, key, name } = this.stateInfo;
      window.open(
        `${origin}${pathname}#/stateDesign?id=${id}&key=${key}&name=${name}`
      );
    },
    // 获取模型关联的流程
    getHmprocessModelList() {
      getHmprocessModelList({ modelCode: this.modelInfo.code }).then((res) => {
        this.processData = res;
      });
    },
    // 查看流程
    handleOpenProcess(record) {
      const { origin, pathname } = window.location;
      const { id, key, name } = record;
      window.open(
        `${origin}${pathname}#/processDesign?id=${id}&key=${key}&name=${name}`
      );
    },
    handleTabClick() {
      if (this.activeTab === "RULE") {
        this.$refs.RuleList.init();
      } else if (this.activeTab === "TRIGGER") {
        this.$refs.TriggerList.init();
      } else if (this.activeTab === "DATAIMPORTEXPORT") {
        this.$refs.DataImportExportList.init();
      }
    },
  },
};
</script>

<style lang="scss" scoped>
@import "@/assets/sass/variables.scss";
.script-color {
  color: $pink;
}

.operation-row {
  position: relative;
  .operation-right {
    position: absolute;
    right: 0;
    top: 0;
  }
}
.label-ellipsis {
  white-space: nowrap;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
</style>
